package com.kuiniu.threeframe.server;

import com.kuiniu.threeframe.Address;
import com.kuiniu.threeframe.client.Client;
import io.netty.channel.ChannelHandlerContext;

import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class SocketMapper {

    private Map<ChannelHandlerContext, ArrayList<Client>> mapChannelToClient = new ConcurrentHashMap<>();
    private Map<String, Client> mapHostUrlToClient = new ConcurrentHashMap<>();

    private SocketMapper() {
    }

    private static final class Holder {
        private static final SocketMapper instance = new SocketMapper();
    }

    public static SocketMapper getInstance() {
        return Holder.instance;
    }


    public void addChannelWithClient(ChannelHandlerContext channel, Client client) {
        if (channel != null && client != null) {
            Address address = client.getAddress();
            if (address != null) {
                String host = address.getUrl();
                if (!mapHostUrlToClient.containsKey(host)) {
                    ArrayList<Client> clients = mapChannelToClient.computeIfAbsent(channel, k -> new ArrayList<>());
                    clients.add(client);
                    mapHostUrlToClient.put(host, client);
                }
            }

        }
    }

    public void removeChannel(ChannelHandlerContext channel) {
        if (channel != null) {
            ArrayList<Client> list = mapChannelToClient.remove(channel);
            if (list != null && !list.isEmpty()) {
                for (Client client : list) {
                    client.close();
                    mapHostUrlToClient.remove(client.getAddress().getUrl());
                }
            }
        }
    }

    public boolean hasClient(String host) {
        if (host == null) {
            return false;
        }
        return mapHostUrlToClient.containsKey(host);
    }

    public Client getClient(String host) {
        return mapHostUrlToClient.get(host);
    }

}
